package main

import (
	"net/http"
	"net/http/httptest"
)

func main() {
	//handleMiddlewareStruct()
	//handleMiddlewareFunc()
	//handleMiddlewareAppend()
	handleMiddlewareModifier()
}

type ModifierMiddleware struct {
	handler http.Handler
}

func (this *ModifierMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	rec := httptest.NewRecorder()
	this.handler.ServeHTTP(rec, r)
	for k, v := range rec.Header() {
		w.Header()[k] = v
	}
	w.Header().Set("go-web-foundation", "vip")
	w.WriteHeader(418)
	w.Write(rec.Body.Bytes())
	w.Write([]byte("\nhey, this is middleware!"))
}

//curl localhost:8080
//curl -I localhost:8080
func handleMiddlewareModifier() {
	http.ListenAndServe(":8080", &ModifierMiddleware{http.HandlerFunc(myHandler3)})
}

func handleMiddlewareAppend() {
	http.ListenAndServe(":8080", &AppendMiddleware{http.HandlerFunc(myHandler3)})
}

type AppendMiddleware struct {
	handler http.Handler
}

func (this *AppendMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	this.handler.ServeHTTP(w, r)
	w.Write([]byte("\nHey, this is middleware!"))
}

func SingleHostFunc(handler http.Handler, allowedHost string) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Host == allowedHost {
			handler.ServeHTTP(w, r)
		} else {
			w.WriteHeader(403)
		}
	})
}

//curl localhost:8080
//curl -I localhost:8080
func handleMiddlewareFunc() {
	http.ListenAndServe(":8080", SingleHostFunc(http.HandlerFunc(myHandler3), "localhost:8080"))
}

type SingleHostStruct struct {
	handler     http.Handler
	allowedHost string
}

func (this *SingleHostStruct) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if r.Host == this.allowedHost {
		this.handler.ServeHTTP(w, r)
	} else {
		w.WriteHeader(403)
	}
}

func myHandler3(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("hello world！"))
}

//curl localhost:8080
//curl -I localhost:8080
func handleMiddlewareStruct() {
	single := &SingleHostStruct{
		handler:     http.HandlerFunc(myHandler3),
		allowedHost: "localhost:8080",
		//allowedhost: "example.com",
	}
	http.ListenAndServe(":8080", single)
}
